#include "Eventfd.hpp"

#include <unistd.h>
#include <sys/eventfd.h>
#include <poll.h>

#include <iostream>


namespace wd
{
Eventfd::Eventfd(EventCallback && cb)
: _eventfd(createEventfd())
, _cb(std::move(cb))
, _isStarted(false)
{

}

Eventfd::~Eventfd()
{
    close(_eventfd);
}

//运行在子线程的
void Eventfd::start()
{
    struct pollfd pfd;
    pfd.fd = _eventfd;
    pfd.events = POLLIN;
    
    _isStarted = true;
    while(_isStarted) {
        int nready = poll(&pfd, 1, 6000);
        if(nready == -1 && errno == EINTR) {
            continue;
        } else if(nready == -1) {
            perror("poll");
            return;
        } else if(nready == 0) {
            printf("poll timeout.\n ");
        } else {
            handleReadEvent();
            if(_cb) {
                _cb();//执行任务
            }
        }
    }
}

void Eventfd::stop()
{
    _isStarted = false;
}


int Eventfd::createEventfd()
{
    int fd = eventfd(0, 0);
    if(fd < 0) {
        perror("eventfd");
    }
    return fd;
}

//处理内核计数器的值(清零)
void Eventfd::handleReadEvent()
{
    uint64_t howmany = 0;
    int ret = read(_eventfd, &howmany, sizeof(howmany));
    printf("\nhowmany: %ld\n", howmany);
    if(ret != sizeof(howmany)) {
        perror("read");
    }
}

void Eventfd::wakeup()
{
    uint64_t one = 1;
    int ret = write(_eventfd, &one, sizeof(one));
    if(ret != sizeof(one)) {
        perror("write");
    }
}

}//end of namespace wd

